using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;

using Pegasus.Diagnostics;
using Pegasus.Runtime.Serialization;

namespace Pegasus.Workflow.Service.FileServices
{
	/// <summary>
	/// Provides a tracking service that logs the event to an XML file.
	/// </summary>
	public class FileTrackingService : WorkflowTrackingService
	{
		// Local Instance Valuse
		private object m_lock = new object();
		private string m_filename;
		private XmlTextWriter m_xmlWriter;
 
		/// <summary>
		/// Initializes a new instance of the <see cref="T:NullTrackingService"/> class.
		/// </summary>
		public FileTrackingService( string filename )
		{
			// Check Parameters
			ParamCode.AssertNotEmpty( filename, "filename" );
			
			m_filename = filename;
		}

		/// <summary>
		/// Starts this instance of the service.
		/// </summary>
		/// <param name="workflowService"></param>
		public override void Start( WorkflowService workflowService )
		{
			// Check Parameters
			ParamCode.AssertNotNull( workflowService, "workflowService" );

			base.Start( workflowService );

			lock( m_lock )
			{
				// Open the file
				m_xmlWriter = new XmlTextWriter( File.Open( m_filename, FileMode.Create, FileAccess.Write, FileShare.None ), Encoding.UTF8 );
				m_xmlWriter.Formatting = Formatting.Indented;

				// Write out the root tag information
				m_xmlWriter.WriteStartDocument();
				m_xmlWriter.WriteStartElement( "WorkflowTracking" );
				m_xmlWriter.WriteAttributeString( "StartDate", DateTime.Now.ToString() );
			}
		}

		/// <summary>
		/// Stops this instance of the service.
		/// </summary>
		public override void Stop()
		{
			base.Stop();

			lock( m_lock )
			{
				if( m_xmlWriter != null )
				{
					m_xmlWriter.WriteEndElement();
					m_xmlWriter.WriteEndDocument();

					m_xmlWriter.Flush();
					m_xmlWriter.Close();
					m_xmlWriter = null;
				}
			}
		}

		/// <summary>
		/// Records the event.
		/// </summary>
		/// <param name="action">The action.</param>
		/// <param name="context">The context.</param>
		/// <param name="messageName"></param>
		/// <param name="parametersXml"></param>
		protected override void RecordEvent( TrackingActions action, WorkflowContext context, string messageName, string parametersXml )
		{
			// Lock the writer so we are only writing out one record at a time.
			lock( m_lock )
			{
				m_xmlWriter.WriteStartElement( action.ToString() );
				m_xmlWriter.WriteAttributeString( "Date", DateTime.Now.ToString() );
				m_xmlWriter.WriteAttributeString( "WorkflowId", context.WorkflowId.ToString() );
				m_xmlWriter.WriteAttributeString( "CurrentState", context.Workflow.CurrentState );

				if( !string.IsNullOrEmpty( parametersXml ) )
				{
					m_xmlWriter.WriteStartElement( "Parameters" );
					m_xmlWriter.WriteRaw( parametersXml );
					m_xmlWriter.WriteEndElement();
				}

				m_xmlWriter.WriteEndElement();
			}
		}
	}
}
